<template>
  <div class="tinymce-editor">
    <Editor v-model="content" :init="init" :disabled="disabled" @onClick="onClick" />
  </div>
</template>

<script setup lang="ts">
import { ref, watch, onMounted } from "vue";
import tinymce from "tinymce/tinymce";
import Editor from "@tinymce/tinymce-vue";
import { uploadImage } from "@/api/image";

// 核心
import "tinymce/themes/silver/theme";
import "tinymce/models/dom/model";

// 插件
import "tinymce/icons/default";  // 图标
import "tinymce/plugins/advlist"; // 高级列表
import "tinymce/plugins/preview"; // 预览
// import "tinymce/plugins/anchor"; // 锚点
import "tinymce/plugins/autolink"; // 自动链接
// import "tinymce/plugins/autoresize"; // 自动调整大小
import "tinymce/plugins/image"; // 图片
// import "tinymce/plugins/media"; // 视频
import "tinymce/plugins/link"; // 链接
// import "tinymce/plugins/code"; // 代码
import "tinymce/plugins/lists"; // 列表
import "tinymce/plugins/table"; // 表格
import "tinymce/plugins/wordcount"; // 字数统计

// Props 定义
interface Props {
  modelValue?: string;
  disabled?: boolean;
  plugins?: string | string[];
  toolbar?: string | string[];
  config?: Object
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: "",
  disabled: false,
  plugins: "advlist preview autolink lists link image table wordcount",
  toolbar:
    "undo redo | preview | image | forecolor backcolor | bold italic blockquote code | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link table | removeformat paste remove"
});

// Emits 定义
const emit = defineEmits<{
  (e: "update:modelValue", value: string): void;
  (e: "onClick", event: any, editor: any): void;
}>();

// 编辑器内容
const content = ref(props.modelValue);

// 编辑器配置
const init = {
  language_url: "/tinymce/langs/zh_CN.js", // 语言包路径
  language: "zh_CN", // 语言
  skin_url: "/tinymce/skins/ui/oxide", // 皮肤路径
  content_css: "/tinymce/skins/content/default/content.min.css", // 内容样式
  height: 300, // 编辑器高度
  max_height: 1000, // 编辑器最大高度
  plugins: props.plugins, // 插件
  toolbar: props.toolbar, // 工具栏
  branding: false, // 品牌信息
  promotion: false, // 推广
  menubar: true, // 菜单栏
  elementpath: false, // 元素路径
  statusbar: false, // 状态栏
  // 修改图片上传处理器
  images_upload_handler: async (blobInfo: any) => {
    try {
      const formData = new FormData(); // 修正变量名
      formData.append("image", blobInfo.blob());
      const response = await uploadImage(formData);

      if (response) {
        return response
      } else {
        throw new Error(response.message || "上传失败");
      }
    } catch (error) {
      throw new Error("图片上传失败，请重试");
    }
  },
  // 文件选择配置
  file_picker_types: "image",
  images_file_types: "jpg,jpeg,png,gif",
  image_advtab: true,
  // 允许拖拽上传
  draggable_modal: true,
  // 图片上传配置
  // images_upload_base_path: import.meta.env.VITE_API_URL,
  // 图片上传URL验证
  images_upload_credentials: true,
  // debug: true // 开启调试模式，方便排查问题
  ...props.config
};

// 监听 props 变化
watch(
  () => props.modelValue,
  newValue => {
    if (content.value !== newValue) {
      content.value = newValue;
    }
  }
);

// 监听内容变化
watch(
  () => content.value,
  newValue => {
    emit("update:modelValue", newValue);
  }
);

// 点击事件处理
const onClick = (e: any) => {
  emit("onClick", e, tinymce);
};

// 清空内容方法
const clear = () => {
  content.value = "";
};

// 初始化编辑器
onMounted(() => {
  tinymce.init({});
});

// 暴露方法给父组件
defineExpose({
  clear
});
</script>

<style lang="scss" scoped>
.tinymce-editor {
  width: 100%;
}

:deep(.tox-tinymce) {
  border-radius: 10px;
}
</style>

<style lang="scss">
.tox-tinymce-aux {
  z-index: 99999 !important;
}

.tinymce.ui.FloatPanel {
  z-index: 99;
}
</style>
